package com.kabigon.tiny.controller;

import com.kabigon.tiny.convert.MemberConvert;
import com.kabigon.tiny.convert.MemberSpringConvert;
import com.kabigon.tiny.convert.ProductConvert;
import com.kabigon.tiny.convert.ProductRoundConvert;
import com.kabigon.tiny.dto.MemberDto;
import com.kabigon.tiny.dto.MemberOrderDto;
import com.kabigon.tiny.dto.ProductDto;
import com.kabigon.tiny.po.Member;
import com.kabigon.tiny.po.Order;
import com.kabigon.tiny.po.Product;
import com.kabigon.tiny.pojo.response.CommonResponse;
import com.kabigon.tiny.util.LocalJsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * MapStruct对象转换测试 controller
 * @author xu.biao
 * @version v1.0
 * @Package com.kabigon.tiny.controller
 * @data 2022/5/28 22:31
 */
@RestController
@RequestMapping("/mapstruct")
public class MapStructController {

    @Autowired
    private MemberSpringConvert memberSpringConvert;

    /**
     * 基本映射
     * @return
     */
    @GetMapping("/baseMapping")
    public CommonResponse baseTest() {
        List<Member> memberList = LocalJsonUtil.getListFormJson("json/members.json", Member.class);
        MemberDto memberDto = MemberConvert.INSTANCE.toDto(memberList.get(0));
        return new CommonResponse(memberDto);
    }

    /**
     * 集合映射
     * @return
     */
    //@GetMapping("/collectionMapping")
    //public CommonResponse collectionTest() {
    //    List<Member> memberList = LocalJsonUtil.getListFormJson("json/members.json", Member.class);
    //    List<MemberDto> memberDtoList = MemberConvert.INSTANCE.toDtoList(memberList);
    //    return new CommonResponse(memberDtoList);
    //}

    public <R, T> Set<R> convertSet(Collection<T> form, Function<T, R> func) {
        return form.stream().map(func).filter(Objects::nonNull).collect(Collectors.toSet());
    }

    /**
     * 子对象映射
     * @return
     */
    /*@GetMapping("/subMapping")
    public CommonResponse subMapping() {
        List<Order> orderList = getOrderList();
        OrderDto orderDto = OrderConvert.INSTANCE.toDto(orderList.get(0));
        return new CommonResponse(orderDto);
    }*/

    /**
     * 组合映射
     * @return
     */
    @GetMapping("/compositeMapping")
    public CommonResponse compositeMapping() {
        List<Order> orderList = LocalJsonUtil.getListFormJson("json/orders.json", Order.class);
        List<Member> memberList = LocalJsonUtil.getListFormJson("json/members.json", Member.class);
        Member member = memberList.get(0);
        Order order = orderList.get(0);
        MemberOrderDto memberOrderDto = MemberConvert.INSTANCE.toMemberOrderDto(member, order);
        return new CommonResponse(memberOrderDto);
    }

    /**
     * 使用依赖注入
     * @return
     */
    @GetMapping("/springMapping")
    public CommonResponse springMapping() {
        List<Member> memberList = LocalJsonUtil.getListFormJson("json/members.json", Member.class);
        MemberDto memberDto = memberSpringConvert.toDto(memberList.get(0));
        return new CommonResponse(memberDto);
    }

    /**
     * 使用常量、默认值和表达式
     * @return
     */
    @GetMapping("/defaultMapping")
    public CommonResponse defaultMapping() {
        List<Product> productList = LocalJsonUtil.getListFormJson("json/products.json", Product.class);
        Product product = productList.get(0);
        product.setId(100L);
        product.setCount(null);
        ProductDto productDto = ProductConvert.INSTANCE.toDto(product);
        return new CommonResponse(productDto);
    }

    @GetMapping("/customMapping")
    public CommonResponse customMapping() {
        List<Product> list = LocalJsonUtil.getListFormJson("json/products.json", Product.class);
        Product product = list.get(0);
        product.setPrice(new BigDecimal(-1));
        ProductDto productDto = ProductRoundConvert.INSTANCE.toDto(product);
        return new CommonResponse(productDto);
    }

    private List<Order> getOrderList() {
        List<Order> orderList = LocalJsonUtil.getListFormJson("json/orders.json", Order.class);
        List<Product> productList = LocalJsonUtil.getListFormJson("json/products.json", Product.class);
        List<Member> memberList = LocalJsonUtil.getListFormJson("json/members.json", Member.class);
        for (int i = 0; i < orderList.size(); i++) {
            Order order = orderList.get(i);
            order.setMember(memberList.get(i));
            order.setProductList(productList);
        }
        return orderList;
    }
}
